FROM eclipse-temurin:17-jre-alpine

WORKDIR /app

COPY ./gradle-center/build/libs/gradle-center.jar gradle-center.jar

# 设置容器运行时默认的 JVM 参数和环境变量
# 注意：环境变量在构建时无法直接用于 ENV 指令的值中，但可以在运行时通过 shell 形式或入口点脚本解析
# 合并多个 ENV 指令以减少镜像层数
ENV DEFAULT_JVM_OPTS="-Xms512m -Xmx512m \
  -XX:+HeapDumpOnOutOfMemoryError \
  -XX:HeapDumpPath=/app/logs/heapdump.hprof \
  -XX:+ExitOnOutOfMemoryError \
  -Djava.net.preferIPv4Stack=true \
  -Dfile.encoding=UTF-8 \
  -Djava.security.egd=file:/dev/./urandom" \
  PROFILES="dev" \
  SNOWFLAKE_ENABLED=false \
  DATACENTER_ID=0 \
  WORKER_ID=0

# 暴露端口
EXPOSE 30000

# 使用 ENTRYPOINT 设置固定的启动命令，CMD 设置默认参数，这样运行时可以被覆盖[1,3](@ref)
#ENTRYPOINT ["sh", "-c", "java $DEFAULT_JVM_OPTS -Dsnowflake.enabled=$SNOWFLAKE_ENABLED -Dsnowflake.datacenter-id=$DATACENTER_ID -Dsnowflake.worker-id=$WORKER_ID -jar gradle-center.jar --spring.profiles.active=$PROFILES " ]

# ENTRYPOINT 使用 exec 形式，允许在 docker run 时追加参数覆盖 CMD
ENTRYPOINT ["sh", "-c", "exec java $DEFAULT_JVM_OPTS \
  -Dsnowflake.enabled=$SNOWFLAKE_ENABLED \
  -Dsnowflake.datacenter-id=$DATACENTER_ID \
  -Dsnowflake.worker-id=$WORKER_ID \
  -jar gradle-center.jar \"$@\"", "--"]
#ENTRYPOINT ["sh", "-c", "exec java ... \"$@\"", "--"]
#实际执行时，Docker 会把 CMD 或 docker run 传入的参数，追加到这个 -- 之后，并且会作为 "$@" 被 shell 展开。
#Docker 实际执行的命令是类似这样的：
#sh -c 'exec java ... -jar gradle-center.jar "$@"' -- --spring.profiles.active=prod

# 使用 CMD 提供默认的启动参数，这些参数会附加到 ENTRYPOINT 之后
# 说明：
# 1. CMD 提供默认参数：如果不指定参数运行容器，会使用此默认值
# 2. docker run 时可以覆盖：在镜像名后添加参数即可覆盖 CMD
#    例如：docker run ... gradle-center:1.0 --spring.profiles.active=prod
# 3. 如果去掉 CMD：
#    - 缺少 profile 参数
#    - docker run 时传入的参数仍然会生效（通过 ENTRYPOINT 中的 "$@" 接收）
# 建议：保留 CMD 作为默认值，提供便利性
CMD ["--spring.profiles.active=dev"]

# ==================== 构建镜像 ====================
# docker build -f gradle-center/Dockerfile -t gradle-springcloud/gradle-center:1.0 .

# ==================== Windows 运行方式 ====================
# 
# 方式1：使用默认 CMD 参数（dev profile）
# docker run -d -p 30000:30000 --name=gradle-center gradle-springcloud/gradle-center:1.0
# 结果：使用 CMD 的默认值 --spring.profiles.active=dev
#
# 方式2：覆盖 CMD 参数（指定 prod profile）
# docker run -d -p 30000:30000   -e PROFILES=prod   -e SNOWFLAKE_ENABLED=true   -e DATACENTER_ID=0   -e WORKER_ID=0   --name=gradle-center   gradle-springcloud/gradle-center:1.0   --spring.profiles.active=prod
# 结果：覆盖 CMD，使用 --spring.profiles.active=prod
#
# 方式3：如果去掉 CMD，必须每次都提供参数
# docker run -d -p 30000:30000 --name=gradle-center gradle-springcloud/gradle-center:1.0 --spring.profiles.active=dev
# 结果：必须提供参数，否则应用可能启动失败

# ==================== Linux 运行方式（完整示例）====================
# 说明：所有 -- 开头的参数都可以直接拼接，用空格分隔
# 最后的 --spring.profiles.active=prod 是传递给容器内应用的参数（不是 Docker 参数）
# docker run -d \
#   -p 30000:30000 \
#   -e PROFILES=prod \
#   -e SNOWFLAKE_ENABLED=true \
#   -e DATACENTER_ID=0 \
#   -e WORKER_ID=0 \
#   --name=gradle-center \
#   --mount type=bind,source=/etc/localtime,target=/etc/localtime,readonly \
#   --mount type=bind,source=/etc/timezone,target=/etc/timezone,readonly \
#   --restart=unless-stopped \
#   gradle-springcloud/gradle-center:1.0 \
#   --spring.profiles.active=prod

#可以考虑挂载出来/app/logs日志，或者类似数据库等数据

#Windows 系统
#默认路径： C:\ProgramData\Docker\volumes\gradle-center-logs\_data
#或者： C:\ProgramData\docker\volumes\gradle-center-logs\_data
#Linux 系统
#默认路径： /var/lib/docker/volumes/gradle-center-logs/_data

# 命名卷（Docker 管理路径）
#-v gradle-center-logs:/app/logs
#
## 绑定挂载（用户指定宿主机路径）
#-v /宿主机/自定义路径:/app/logs


# ==================== 参数说明 ====================
# Docker 参数（可以任意组合，用空格分隔）：
#   -p 30000:30000                    # 端口映射
#   -e KEY=VALUE                      # 环境变量
#   --name=容器名                      # 容器名称
#   --mount type=bind,...             # 挂载（时间同步）
#   --memory="1g"                     # 内存限制
#   --cpus="1.0"                      # CPU 限制
#   --restart=unless-stopped          # 重启策略
#   -v volume名:容器路径               # 数据卷挂载
#   -d                                # 后台运行
#   --network=网络名                   # 指定网络
#   --link=容器名                      # 链接其他容器
#   等等...
#
# 容器内应用参数（放在镜像名之后，会传递给 ENTRYPOINT/CMD）：
#   --spring.profiles.active=prod     # Spring Boot 配置
#   其他应用启动参数...
#
# 注意：镜像名之前的是 Docker 参数，镜像名之后的是应用参数

